Organize versioned controllers into subdirectories (v1/, v2/) within each feature module folder. The feature module imports both controller classes. Shared DTOs live in a dto/ subdirectory outside the version folders. For small APIs, version-specific logic can live in service methods instead of separate service classes.
v1/ and v2/ subdirectories keep version-specific code isolated and independently testable.
Shared DTOs go in a common dto/ folder — versioning only applies to the request/response layer.
For large teams, separate service classes per version prevent one version's changes from breaking another.
For small APIs, a single service with version-branching logic is acceptable to avoid code duplication.
The module registers all controller versions — clients route to the right one via the versioning strategy.